package obsluga;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableModel;

import org.jfree.chart.JFreeChart;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import przykladyWykresow.ChartPanelAbstract;
import przykladyWykresow.DynamicChartPanelAbstract;
import przykladyWykresow.WykresDynamiczny1;
import przykladyWykresow.WykresDynamiczny2;
import przykladyWykresow.WykresKolowy;
import przykladyWykresow.WykresLiniowy;
import przykladyWykresow.WykresSlupkowy;
import przykladyWykresow.WykresySinusoidalne;

@SuppressWarnings("serial")
public class prezentacjaWykresow extends ApplicationFrame {

	String newline = "\n";

	JTextArea textArea = new JTextArea();

	// przyciski
	JButton pdfButton = setJButtonAction("Zapisz wykres do PDF",
			"Przycisk exportujący wykres do pliku PDF");
	JButton odswiezWykres = setJButtonAction("Odswież wykres",
			"Odswieżanie wykresu");

	// radio butony do wybierania wykresów
	JRadioButton radioButton1wykres1 = setRadioButtonAction(
			"Wykresy sinusoidalne", "Wybranie wykresu złożonego");
	JRadioButton radioButton2wykres2 = setRadioButtonAction("Dual Axis Chart",
			"Wybranie wykresów Słupkowych");
	JRadioButton radioButton3wykres3 = setRadioButtonAction("Wykres kołowy",
			"Wybranie wykresu kołowego");
	JRadioButton radioButton3wykres31 = setRadioButtonAction(
			"Wykres kołowy 2d", "Wybranie wykresu kołowego 2d");
	JRadioButton radioButton3wykres32 = setRadioButtonAction(
			"Wykres kołowy 3d", "Wybranie wykresu kołowego 3d");
	JRadioButton radioButton4wykres4 = setRadioButtonAction("Wykres Liniowy",
			"Wybranie wykresu liniowego");
	JRadioButton radioButton5wykres5 = setRadioButtonAction(
			"Wykres dynamiczny",
			"Wykres dynamiczny pokazujący zużycie pamięci JVM");
	JRadioButton radioButton6wykres6 = setRadioButtonAction(
			"Wykres dynamiczny 2", "Wykres dynamiczny w dziedzinie czasu");
	// panele
	JPanel panelCentralny = new JPanel();
	JPanel panelPrawy = new JPanel();
	JPanel panelLewy = new JPanel();
	JPanel panelTabeli = new JPanel();
	JPanel panelDolnyKodu = new JPanel();

	JScrollPane scrollpane;
	DefaultTableModel dtm;
	JTable tabel;
	// mapa wykresów
	Map<JRadioButton, JPanel> chartList = new LinkedHashMap<JRadioButton, JPanel>();
	// nazwa wykresu
	JTextField jtextNazwaWykresu = new JTextField();
	JLabel labelNazwaWykresu = new JLabel("Nazwa Wykresu:");
	// wykresy
	ChartPanelAbstract CP1 = new WykresySinusoidalne("Wykresy Sinusoidalne");
	ChartPanelAbstract CP2 = new WykresSlupkowy("Wykres słupkowy");
	ChartPanelAbstract CP3 = new WykresKolowy("Wykres Kołowy 2d",
			"Wykres Kołowy 3d", true);
	ChartPanelAbstract CP4 = new WykresLiniowy("Wykres Liniowy");
	WykresDynamiczny1 dynamicPanel1 = new WykresDynamiczny1(30000);
	WykresDynamiczny2 dynamicPanel2 = new WykresDynamiczny2("Wykres dynamiczny");

	/**
	 * 
	 * @param title
	 *            the frame title.
	 */
	public prezentacjaWykresow(String title) {

		super(title);
		setResizable(false);
		int height = 550;
		int panelsHeight = 400;
		dynamicPanel1.new DataGenerator(100).start();
		dynamicPanel2.start();
		setContentPane(panelCentralny);
		panelCentralny.setLayout(null);

		panelLewy.setBounds(0, 0, 220, 400);
		// panelLewy.setBounds(x, y, width, height);
		panelLewy.setLayout(null);
		// panelLewy.setBackground(Color.BLUE);
		panelCentralny.add(panelLewy);

		panelPrawy.setBounds(panelLewy.getWidth(), 0, 400 + 425, panelsHeight);
		panelPrawy.setLayout(null);
		panelCentralny.add(panelPrawy);

		panelTabeli.setBounds(400, 0, 425, panelsHeight);
		panelTabeli.setLayout(null);
		panelCentralny.setPreferredSize(new Dimension(panelLewy.getWidth()
				+ panelPrawy.getWidth(), height));

		// TODO
		panelDolnyKodu.setBounds(-3, panelsHeight, panelLewy.getWidth()
				+ panelPrawy.getWidth() + 12, height - panelsHeight + 10);
		panelDolnyKodu.setLayout(null);
		panelCentralny.add(panelDolnyKodu);

		dtm = new DefaultTableModel();
		dtm.setColumnCount(3);
		dtm.setRowCount(6);
		dtm.setColumnIdentifiers(new Object[] { "Lp", "Nazwa kategorii",
				"Wartość liczbowa" });
		tabel = new JTable(dtm);

		JPanel p1 = new JPanel();
		p1.setLayout(null);
		labelNazwaWykresu.setBounds(1, 1, 120, 20);
		jtextNazwaWykresu.setBounds(labelNazwaWykresu.getX()
				+ labelNazwaWykresu.getWidth(), 1, 300, 20);
		p1.add(labelNazwaWykresu);
		p1.add(jtextNazwaWykresu);
		p1.setBounds(1, 6, panelTabeli.getWidth() - 2, 30);

		scrollpane = new JScrollPane(tabel);
		scrollpane.setBounds(1, p1.getY() + p1.getHeight() + 10,
				panelTabeli.getWidth() - 2, 150);
		tabel.getColumnModel().getColumn(0).setMaxWidth(35);
		tabel.getColumnModel().getColumn(1).setPreferredWidth(200);

		odswiezWykres.setBounds(12, panelTabeli.getHeight() - (25 + 10), 203,
				25);

		ButtonGroup radioButton3wykres3x = new ButtonGroup();
		radioButton3wykres31.setSelected(true);
		radioButton3wykres31.setBounds(12,
				scrollpane.getY() + scrollpane.getHeight() + 5,
				panelLewy.getWidth() - 11 * 2, 23);
		radioButton3wykres32.setBounds(12, radioButton3wykres31.getY()
				+ radioButton3wykres31.getHeight() + 5,
				panelLewy.getWidth() - 11 * 2, 23);
		radioButton3wykres3x.add(radioButton3wykres31);
		radioButton3wykres3x.add(radioButton3wykres32);

		panelTabeli.add(scrollpane);
		panelTabeli.add(odswiezWykres);
		panelTabeli.add(radioButton3wykres31);
		panelTabeli.add(radioButton3wykres32);
		panelTabeli.add(p1);

		panelPrawy.add(panelTabeli);

		addChartsAndButtons(panelLewy, panelPrawy);

	}

	/**
	 * The starting point for the demo.
	 * 
	 * @param args
	 *            ignored.
	 */
	public static void main(String[] args) {
		prezentacjaWykresow demo = new prezentacjaWykresow("Wykresy");
		demo.pack();
		RefineryUtilities.centerFrameOnScreen(demo);
		demo.setVisible(true);
	}

	private class SwingActionForRadioButtons extends AbstractAction {
		public SwingActionForRadioButtons(String name, String description) {
			putValue(NAME, name);
			putValue(SHORT_DESCRIPTION, description);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == radioButton3wykres31) {
				((WykresKolowy) CP3).set2d(true);
				jtextNazwaWykresu.setText(CP3.getTitle());
				CP3.refresh();
			} else if (e.getSource() == radioButton3wykres32) {
				((WykresKolowy) CP3).set2d(false);
				jtextNazwaWykresu.setText(CP3.getTitle());
				CP3.refresh();
			} else {
				setAllVisibleFalse();
				chartList.get(e.getSource()).setVisible(true);

				// obsluga panelu dolnego odpowiedzialnego za pokazywanie czesci
				// kodu wykresu
				zmienKodZrodlowy(chartList.get(e.getSource()).getClass()
						.getSimpleName());

				if (chartList.get(e.getSource()) instanceof ChartPanelAbstract) {
					panelTabeli.setVisible(true);
					jtextNazwaWykresu.setText(((ChartPanelAbstract) chartList
							.get(e.getSource())).getTitle());
					if (czytajPlik((ChartPanelAbstract) chartList.get(e
							.getSource()))) {
						scrollpane.setVisible(true);
					} else {
						scrollpane.setVisible(false);
					}

					if (e.getSource() == radioButton3wykres3) {
						radioButton3wykres31.setVisible(true);
						radioButton3wykres32.setVisible(true);
					}
				}
			}
		}
	}

	private void setAllVisibleFalse() {
		for (JPanel chartPanel : chartList.values()) {
			chartPanel.setVisible(false);
		}
		radioButton3wykres31.setVisible(false);
		radioButton3wykres32.setVisible(false);
		panelTabeli.setVisible(false);
		scrollpane.setVisible(false);
	}

	private void addChartsAndButtons(JPanel panelLewy, JPanel panelPrawy) {
		ButtonGroup buttonGroup = new ButtonGroup();

		chartList.put(radioButton1wykres1, CP1);
		chartList.put(radioButton2wykres2, CP2);
		chartList.put(radioButton3wykres3, CP3);
		chartList.put(radioButton4wykres4, CP4);
		chartList.put(radioButton5wykres5, dynamicPanel1);
		chartList.put(radioButton6wykres6, dynamicPanel2);

		for (JPanel chartPanel : chartList.values()) {
			panelPrawy.add(chartPanel);
			chartPanel.setBounds(0, 0, 400, 400);
		}

		int i = 0;
		for (JRadioButton jRadioButton : chartList.keySet()) {
			panelLewy.add(jRadioButton);
			buttonGroup.add(jRadioButton);
			jRadioButton.setBounds(11, 5 + 28 * i,
					panelLewy.getWidth() - 11 * 2, 23);
			i++;
		}

		pdfButton.setBounds(11, panelLewy.getHeight() - (25 + 10),
				panelLewy.getWidth() - 11 * 2, 25);
		panelLewy.add(pdfButton);

		dodajZrodloKodu(panelDolnyKodu);
		zmienKodZrodlowy("WykresySinusoidalne");
		setAllVisibleFalse();
		// first chart - default visible
		radioButton1wykres1.setSelected(true);
		CP1.setVisible(true);
		jtextNazwaWykresu.setText(CP1.getTitle());
		dynamicPanel1.setBounds(0, 0, panelPrawy.getWidth(), 400);
		dynamicPanel2.setBounds(0, 0, panelPrawy.getWidth(), 400);
		panelTabeli.setVisible(true);
	}

	private class SwingActionForJButtons extends AbstractAction {
		public SwingActionForJButtons(String name, String description) {
			putValue(NAME, name);
			putValue(SHORT_DESCRIPTION, description);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == pdfButton) {
				for (JPanel chartPanel : chartList.values()) {
					if (chartPanel.isVisible()) {
						if (chartPanel instanceof DynamicChartPanelAbstract) {
							writeChartToPDF(((DynamicChartPanelAbstract) chartPanel)
									.getChartPanel().getChart());
						} else {
							writeChartToPDF(((ChartPanelAbstract) chartPanel)
									.getChart());
						}
						break;
					}
				}
			} else if (e.getSource() == odswiezWykres) {
				getSelectedChart().setTitle(jtextNazwaWykresu.getText());
				getSelectedChart().setHashMapDataSet(wczytajWykres());
				getSelectedChart().refresh();
			}
		}

		private ChartPanelAbstract getSelectedChart() {
			for (JPanel chartPanel : chartList.values()) {
				if (chartPanel.isVisible()) {
					return (ChartPanelAbstract) chartPanel;
				}
			}
			return null;
		}
	}

	public static void writeChartToPDF(JFreeChart PDFPieChart) {
		zapisDoPDFA zapis = new zapisDoPDFA();
		zapis.zapiszPlik(2, PDFPieChart);
	}

	private JRadioButton setRadioButtonAction(String name, String Description) {
		JRadioButton button = new JRadioButton();
		button.setAction(new SwingActionForRadioButtons(name, Description));
		return button;
	}

	private JButton setJButtonAction(String name, String Description) {
		JButton button = new JButton();
		button.setAction(new SwingActionForJButtons(name, Description));
		return button;
	}

	public boolean czytajPlik(ChartPanelAbstract chart) {
		tabel.clearSelection();
		HashMap<String, Integer> hashmap = chart.getHashMapDataSet();
		if (hashmap != null) {
			int i = 0;

			while (dtm.getRowCount() > 0) {
				dtm.removeRow(0);
			}

			i = 1;
			for (Object key : hashmap.keySet()) {
				dtm.addRow(new Object[] { i++, key, hashmap.get(key).toString() });
			}
			return true;
		} else {
			return false;
		}
	}

	public HashMap<String, Integer> wczytajWykres() {
		tabel.clearSelection();
		HashMap<String, Integer> hashmap1 = new LinkedHashMap<String, Integer>();
		int j = 0;
		for (int i = 0; i < tabel.getRowCount(); i++) {
			if ((tabel.getValueAt(i, 1) != null)
					&& (tabel.getValueAt(i, 2) != null)) {
				try {
					hashmap1.put((String) tabel.getValueAt(i, 1), (new Integer(
							(String) tabel.getValueAt(i, 2))));
				} catch (Exception exc) {
					System.out.println("exc" + exc);
				}
			}
			j++;
		}
		if (hashmap1.size() == j) {
			return hashmap1;
		} else {
			JOptionPane
					.showMessageDialog(
							null,
							"Błędny format danych w tabeli. W kolumnie drugiej dane nie moga sie powtarzac!!");
			return null;
		}
	}

	private void dodajZrodloKodu(JPanel panel) {

		int odstep = 11;

		textArea.setColumns(20);
		textArea.setLineWrap(true);
		textArea.setRows(5);
		textArea.setWrapStyleWord(true);
		textArea.setEditable(false);

		JScrollPane jscrollPane;
		jscrollPane = new JScrollPane(textArea);
		jscrollPane.setAutoscrolls(true);

		// JTextField text = new JTextField(4);
		panel.add(jscrollPane);
		JLabel labelka = new JLabel("Kod źródłowy:");
		labelka.setBounds(odstep, 6, 110, 25);
		panel.add(labelka);

		// This creates a nice frame.

		Border compound;
		compound = BorderFactory.createCompoundBorder(
				BorderFactory.createRaisedBevelBorder(),
				BorderFactory.createLoweredBevelBorder());

		// compound = BorderFactory.createLineBorder(Color.BLACK);
		panel.setBorder(compound);

		jscrollPane.setBounds(labelka.getX() + labelka.getWidth(), 4,
				panel.getWidth() - (labelka.getX() + labelka.getWidth() + 4),
				panel.getHeight() - 10);
		jscrollPane.setToolTipText("Kod użyty do budowy wykresu");

	}

	private void zmienKodZrodlowy(String file) {
		InputStream in = this.getClass().getClassLoader()
				.getResourceAsStream("zrodlakodu/" + file);
		try {
			textArea.read(new InputStreamReader(in), null);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}